using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.Windows.Media.Media3D;
using _3DHouse.CustomControl;


namespace _3DHouse.Lib
{
    /// <summary>
    /// 用于撤消和重做的类
    /// </summary>
    public class UnDoRedo
    {
        /// <summary>
        /// 撤消队列
        /// </summary>
        private Stack<ICommand> _Undocommands = new Stack<ICommand>();
        /// <summary>
        /// 重做队列
        /// </summary>
        private Stack<ICommand> _Redocommands = new Stack<ICommand>();

        private Viewport3D _Container;
        /// <summary>
        /// 当前场景
        /// </summary>
        public Viewport3D Container
        {
            get { return _Container; }
            set { _Container = value;}                    
        }
        /// <summary>
        /// 重做
        /// </summary>
        /// <param name="levels">重做步数</param>
        public void Redo(int levels)
        {
            for (int i = 1; i <= levels; i++)
            {
                if (_Redocommands.Count != 0)
                {
                    //移除并返回位于 队列顶部的对象,
                    ICommand command = _Redocommands.Pop();                    
                    command.Execute();//重做
                    _Undocommands.Push(command);//将对象插入队列 的顶部
                }
            }
        }
        /// <summary>
        /// 撤消
        /// </summary>
        /// <param name="levels">撤消步数</param>
        public void Undo(int levels)
        {
            for (int i = 1; i <= levels; i++)
            {
                if (_Undocommands.Count != 0)
                {
                    ICommand command = _Undocommands.Pop();
                    command.UnExecute();//撤消
                    _Redocommands.Push(command);
                }
            }
        }

        #region UndoHelperFunctions
        /// <summary>
        /// 插入撤消队列（添加对象）
        /// </summary>
        /// <param name="ApbOrDevice">添加的对象</param>
        public void InsertInUnDoRedoForInsert(Cube model)
        {
            ICommand cmd = new InsertCommand(model, Container);
            _Undocommands.Push(cmd); _Redocommands.Clear();
        }
        /// <summary>
        /// 插入撤消队列（删除对象）
        /// </summary>
        /// <param name="ApbOrDevice">删除的对象</param>
        public void InsertInUnDoRedoForDelete(Cube model)
        {
            ICommand cmd = new DeleteCommand(model, Container);
            _Undocommands.Push(cmd); _Redocommands.Clear();
        }
        /// <summary>
        /// 插入撤消队列（移动对象）
        /// </summary>
        /// <param name="x">X轴移动数值</param>
        /// <param name="y">Y轴移动数值</param>
        /// <param name="z">Z轴移动数值</param>
        /// <param name="model">要移动的对象</param>
        public void InsertInUnDoRedoForMove
        (double x, double y, double z, Cube model)
        {
            ICommand cmd = new MoveCommand(x, y, z, model);
            _Undocommands.Push(cmd); _Redocommands.Clear();
        }
        /// <summary>
        /// 尺寸修改
        /// </summary>
        /// <param name="margin">更的边界</param>
        /// <param name="width">更的宽带,缩小就用负值</param>
        /// <param name="height">更改的高度,缩小就用负值</param>
        /// <param name="UIelement">改变的控件</param>

    //    public void InsertInUnDoRedoForResize
    //(double x, double y, double z, Cube UIelement)
    //    {
    //        ICommand cmd = new ResizeCommand(x,y, z, UIelement);
    //        _Undocommands.Push(cmd); _Redocommands.Clear();
    //    }
        /// <summary>
        /// 插入撤消队列(拉伸更改)
        /// </summary>
        /// <param name="oldModel">旧的对象</param>
        /// <param name="UIelement">更改后的对象</param>
        public void InsertInUnDoRedoForResize(Cube oldModel, Cube model)
        {
            ICommand cmd = new ResizeCommand(oldModel, model);
            _Undocommands.Push(cmd); _Redocommands.Clear();
        }
        /// <summary>
        /// 插入撤消队列(旋转对象)
        /// </summary>
        /// <param name="angle">旋转角度</param>
        /// <param name="model">旋转的对象</param>
        public void InsertInUnDoRedoForRotate(double angle, Cube model)
        {
            ICommand cmd = new RotateCommand(model, angle);
            _Undocommands.Push(cmd); _Redocommands.Clear();
        }
        #endregion
        /// <summary>
        /// 清空队列
        /// </summary>
       public void Cler()
        {
            _Redocommands.Clear();
            _Undocommands.Clear();
        }
    } 
}
